/* ============================================================================== 
2  * NET Framework：4.0.30319.18408
3  * 创 建 者：$projectname$.qd01.zhouwei 
4  * 创建日期：2014/9/28 10:41:13  
5  * 功能说明：
6  * 引用说明：
* ==============================================================================*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections;
//using System.s
namespace TEmit
{
    /******
     * 
/// <summary>
     /// 获取RateCode表一条数据
     /// </summary>
     /// <param name="rateCodeID">主键ID</param>
     /// <returns>RateCode实体</returns>
     internal static SOAEntity.RateCodeEntity GetDataById(int rateCodeID)
     {
         RateCodeEntity productEntity = ProductBusiness.RateCodeBusiness.HotelPubDB.GetDataById(rateCodeID);
         return Tool.TranslateEntity<RateCodeEntity, SOAEntity.RateCodeEntity>(productEntity);
     }
     * ******/
    public  class ObjectExt
    {
        /// <summary>
        /// 深复制
        /// </summary>
        /// <param name="obj">请求对象</param>
        /// <returns>返回对象</returns>
        public static object CopyData(object obj)
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                BinaryFormatter formatter = new BinaryFormatter();

                formatter.Serialize(memoryStream, obj);
                memoryStream.Position = 0;

                return formatter.Deserialize(memoryStream);
            }
        }


        /// <summary>
        /// 复制实体类中相同类型并且相同名称的属性值
        /// </summary>
        /// <param name="inputEntity">输入实体</param>
        /// <param name="outputEntity">输出实体</param>
        public static void CopyData(object inputEntity, object outputEntity)
        {
            if (inputEntity == null || outputEntity == null)
            {
                return;
            }

            Type inputEntityType = inputEntity.GetType();
            Type outputEntityType = outputEntity.GetType();

            foreach (PropertyInfo inputEntityProperty in inputEntityType.GetProperties())
            {
                foreach (PropertyInfo outputEntityProperty in outputEntityType.GetProperties())
                {
                    object inputValue = inputEntityProperty.GetValue(inputEntity, null);

                    if (inputValue != null
                        && inputEntityProperty.Name == outputEntityProperty.Name
                        && inputEntityProperty.PropertyType.Name == outputEntityProperty.PropertyType.Name)
                    {
                        outputEntityProperty.SetValue(outputEntity, inputValue, null);
                        break;
                    }
                }
            }
        }

        /// <summary>
        /// 类型转换，用于具有相同属性的类的转换
        /// </summary>
        /// <typeparam name="OldType">旧类型</typeparam>
        /// <typeparam name="NewType">新类型</typeparam>
        /// <param name="oldEntity">旧实体</param>
        /// <returns>新实体</returns>
        public static NewType TranslateEntity<OldType, NewType>(OldType oldEntity)
        {
            NewType newEntity = Activator.CreateInstance<NewType>();
            Type t = typeof(NewType);
            Type oldType = typeof(OldType);
            foreach (PropertyInfo propertyInfo in t.GetProperties())
            {
                if (oldType.GetProperty(propertyInfo.Name) == null)
                {
                    continue;
                }
                object oldValue = oldType.GetProperty(propertyInfo.Name).GetValue(oldEntity, null);
                object newValue = t.GetProperty(propertyInfo.Name).GetValue(newEntity, null);
                if (oldValue != null && oldValue.GetType().Name == (new List<object>()).GetType().Name)
                {
                    IList oldObjList = (IList)oldValue;
                    if (oldObjList.Count < 0)
                    {
                        continue;
                    }
                    Type oldValueType = oldObjList[0].GetType();
                    Type newValueType = propertyInfo.PropertyType.GetGenericArguments()[0];

                    IList newObjList = (IList)newValue;
                    foreach (object item in oldObjList)
                    {
                        object newItem = TranslateDynamicsEntity(newValueType, item);
                        newObjList.Add(newItem);
                    }
                    newValue = newObjList;
                }
                else
                {
                    newValue = oldType.GetProperty(propertyInfo.Name).GetValue(oldEntity, null);
                }
                propertyInfo.SetValue(newEntity, newValue, null);
            }
            return newEntity;
        }
        /// <summary>
        /// 类型转换
        /// </summary>
        /// <param name="newEntityType">新实体的类型</param>
        /// <param name="oldEntity">旧实体</param>
        /// <returns>新实体</returns>
        private static object TranslateDynamicsEntity(Type newEntityType, object oldEntity)
        {
            object newEntity = Assembly.GetAssembly(newEntityType).CreateInstance(newEntityType.FullName);
            Type newType = newEntity.GetType();
            Type oldType = oldEntity.GetType();
            foreach (PropertyInfo propertyInfo in newType.GetProperties())
            {
                object oldValue = oldType.GetProperty(propertyInfo.Name).GetValue(oldEntity, null);
                object newValue = newType.GetProperty(propertyInfo.Name).GetValue(newEntity, null);
                if (oldValue != null && oldValue.GetType().Name == (new List<object>()).GetType().Name)
                {
                    IList oldObjList = (IList)oldValue;
                    if (oldObjList.Count < 0)
                    {
                        continue;
                    }
                    Type oldValueType = oldObjList[0].GetType();
                    Type newValueType = propertyInfo.PropertyType.GetGenericArguments()[0];

                    IList newObjList = (IList)newValue;
                    foreach (object item in oldObjList)
                    {
                        object newItem = TranslateDynamicsEntity(newValueType, item);
                        newObjList.Add(newItem);
                    }
                    newValue = newObjList;
                }
                else
                {
                    newValue = oldType.GetProperty(propertyInfo.Name).GetValue(oldEntity, null);
                }
                propertyInfo.SetValue(newEntity, newValue, null);
            }
            return newEntity;
        }
    }
}

